﻿Imports System.Text.RegularExpressions
Imports Microsoft.JScript


Public Class ExpressionServiceImpl
    Implements IExpressionService

    Private r As Regex
    Private JSEngine As Vsa.VsaEngine = Vsa.VsaEngine.CreateEngine ' js引擎

    Public Function GetParentPropertyName(ByRef str As String) As String Implements IExpressionService.GetParentPropertyName
        Dim pattern As String = "#([a-zA-Z][a-zA-Z0-9]*)"
        r = New Regex(pattern)
        Return r.Match(str).Groups(1).Value
    End Function

    Public Function GetSelfProPertyName(ByRef str As String) As String Implements IExpressionService.GetSelfProPertyName
        Dim pattern As String = "($[a-zA-Z][a-zA-Z0-9]*)"
        r = New Regex(pattern)
        Return r.Match(str).Value
    End Function

    Public Function GetFunction(ByRef str As String) As String Implements IExpressionService.GetFunction
        Dim pattern As String = "($[a-zA-Z][a-zA-Z0-9]*)"
        r = New Regex(pattern)
        Return r.Match(str).Value
    End Function


    Public Function ReplaceParentPropertyName(ByRef parent As PartEntity, ByRef str As String) As String
        Dim ty As Type = GetType(PartEntity)
        ' 替换父组件属性
        Dim pName As String = GetParentPropertyName(str)
        While pName <> ""
            Dim pValue As Object = ty.GetProperty(pName).GetValue(parent)
            str = str.Replace($"#{pName}", pValue)
            pName = GetParentPropertyName(str)
        End While
        Return str
    End Function

    Public Function ReplaceSelfPropertyName(ByRef self As PartEntity, ByRef str As String) As String
        Dim ty As Type = GetType(PartEntity)


        ' 替换父组件属性
        Dim pName As String = GetSelfProPertyName(str)
        While pName <> ""
            Dim pValue As Object = ty.GetProperty(pName).GetValue(self)
            str = str.Replace($"@{pName}", pValue)
            pName = GetSelfProPertyName(str)
        End While
        Return str
    End Function


    Public Function eavl(ByRef obj As PartEntity, ByRef str As String) As String Implements IExpressionService.eavl

        ' 替换自身属性
        Dim self As Object = obj
        str = ReplaceSelfPropertyName(self, str) ' 如果存在父对象, 执行替换父对象属性

        ' 替换父组件属性
        Dim parent As PartEntity = obj.parent
        If Not parent Is Nothing Then str = ReplaceParentPropertyName(parent, str) ' 如果存在父对象, 执行替换父对象属性


        Return eavl(str)
    End Function

    Public Function eavl_plate(ByRef plate As PartEntity, ByRef str As String)
        str = ReplaceParentPropertyName(plate, str)
        Return eavl(str)
    End Function


    Public Function eavl(ByRef jsCode As String) As String Implements IExpressionService.eavl
        Dim result As Object
        Try
            result = Eval.JScriptEvaluate(jsCode, JSEngine)
            Return result
        Catch ex As Exception
            Return ex.StackTrace
        End Try
    End Function

    Public Function eavl(ByRef dr As DataRow, ByRef jsCode As String) As Object Implements IExpressionService.eavl

        Dim pattern As String = "#([a-zA-Z][a-zA-Z0-9]*)"
        r = New Regex(pattern)

        Dim str As String = jsCode
        Dim pn1 As String = r.Match(str).Groups(0).Value
        Dim pn2 As String = r.Match(str).Groups(1).Value

        While pn1 <> ""
            str = str.Replace(pn1, dr(pn2))
            pn1 = r.Match(str).Groups(0).Value
            pn2 = r.Match(str).Groups(1).Value
        End While


        Dim result As Object
        Try
            result = Eval.JScriptEvaluate(str, JSEngine)
            Return result
        Catch ex As Exception
            Return ex.StackTrace
        End Try

    End Function


    Public Function evalPlate(ByRef dr_parent As DataRow, ByRef dr_self As DataRow, ByRef jsCode As String) As Object Implements IExpressionService.evalPlate
        Dim str As String = jsCode
        Dim pattern As String
        Dim pn1 As String
        Dim pn2 As String


        pattern = "@([a-zA-Z][a-zA-Z0-9]*)"
        r = New Regex(pattern)
        pn1 = r.Match(str).Groups(0).Value
        pn2 = r.Match(str).Groups(1).Value
        While pn1 <> ""
            str = str.Replace(pn1, dr_self(pn2))
            pn1 = r.Match(str).Groups(0).Value
            pn2 = r.Match(str).Groups(1).Value
        End While

        pattern = "#([a-zA-Z][a-zA-Z0-9]*)"
        r = New Regex(pattern)
        pn1 = r.Match(str).Groups(0).Value
        pn2 = r.Match(str).Groups(1).Value
        While pn1 <> ""
            str = str.Replace(pn1, dr_parent(pn2))
            pn1 = r.Match(str).Groups(0).Value
            pn2 = r.Match(str).Groups(1).Value
        End While

        Dim result As Object
        Try
            result = Eval.JScriptEvaluate(str, JSEngine)
            Return result
        Catch ex As Exception
            Return ex.StackTrace
        End Try
    End Function
End Class
